# 定义和使用元类
# 定义一个元类
class MyMeta(type):
    # 元类中的__new__方法,name,bases,attrs是固定的标准参数
    # name: 要创建类的名字，字符串
    # bases: 父类元组
    # attrs: 类属性字典，包含方法和属性
    def __new__(cls, name,bases,attrs):
        print(f"创建类 {name} 使用 MyMeta")
        return super().__new__(cls, name,bases,attrs)

# 使用元类创建类
class MyClass(metaclass=MyMeta):
    pass

# 关于元类中的__new__和__init__方法
class MyMeta2(type):
    def __new__(cls, name,bases,attrs):
        print(f"创建类 {name}")
        attrs['version'] = "1.0.1"
        return super().__new__(cls, name,bases,attrs)

    def __init__(cls, name,bases,attrs):
        print(f"初始化类 {name}")
        super().__init__(name,bases,attrs)

class MyClass2(metaclass=MyMeta2):
    pass

mc2 = MyClass2()
print(dir(mc2)) # 从打印也来的结果看有属性version
print(mc2.version)  # 1.0.1

print("=" * 50)
# 自动注册类
class RegistryMeta(type):
    registry = {}
    def __new__(cls, name,bases,attrs):
        new_class = super().__new__(cls, name,bases,attrs)
        cls.registry[name] = new_class
        return new_class

class Base(metaclass=RegistryMeta):
    pass
class A(Base):
    pass
class B(Base):
    pass

print(RegistryMeta.registry)

print("=" * 50)
# 动态修改类行为
class MyMeta3(type):
    def __init__(cls, name,bases,attrs):
        if 'required_method' not in attrs:
            raise TypeError(f"类 {name} 必须定义 required_method 方法")
        super().__init__(name,bases,attrs)

class MyClass3(metaclass=MyMeta3):
    # 类中必须要有这个属性，否则会抛出异常
    # required_method = "required_method"
    def required_method(self):
        print("执行 required_method 方法")


print("=" * 50)
# 类装饰器与元类
registry = {}
def register_class(cls):
    registry[cls.__name__] = cls
    return cls

#相当于 A = register_class(A)
@register_class
class A:
    pass

print(registry)

print("=========")
# 元类
class MyMeta4(type):
    registry = {}
    def __new__(cls, name,bases,attrs):
        new_class = super().__new__(cls, name,bases,attrs)
        cls.registry[name] = new_class
        return new_class

class B(metaclass=MyMeta4):
    pass

print(MyMeta4.registry)